Conversation
…, and can get total_cost of reservation
…t; test for find_reservations(date) in hotel_booker is red
HotelWhat We're Looking For
Goeun! Good job with this project! I think that your code looks good-- I think that your design is pretty good-- your HotelBooker manages the reservations, rooms, reserved blocks, and unreserved blocks. The complex date overlap logic lives in the DateRange class, which I think really paid off. Overall, my biggest comment is that I truly feel that the tests were thorough, clean, and readable. I in fact have very little comments on the tests because I think they're great-- wish I had more to comment on, but I really think you did a great job on the tests! That being said, I'm adding some comments on specific pieces of code. The main themes on these comments are:
In conclusion: generally good job! I think I could see your code being a tiny bit cleaner, but the DateRange decision and the tests you wrote are really great and overwhelmingly positive. |
| class HotelBooker | ||
| attr_accessor :rooms, :reservations, :unreserved_block, :reserved_block | ||
| NUM_ROOMS = 20 | ||
| BLOCK_MAX = 5 |
lib/hotel_booker.rb
Outdated
| @rooms = [] | ||
|
|
||
| NUM_ROOMS.times do |i| | ||
| @rooms << Hotel::Room.new(i+1) |
There was a problem hiding this comment.
Ruby will be looking for names locally first, prioritizing local names... so, since they're all in the same module, there's no need to namespace Hotel::Room... Room should just work! Same with the rest of the namespacing in the code.
lib/hotel_booker.rb
Outdated
| check_in = Date.parse(check_in) | ||
| check_out = Date.parse(check_out) | ||
| date_range = range(check_in, check_out) | ||
| reservation = Hotel::Reservation.new(id, date_range) |
There was a problem hiding this comment.
It might give you less "overusing the word range"-anxiety to in-line this:
reservation = Hotel::Reservation.new(id, range(check_in, check_out))
lib/hotel_booker.rb
Outdated
| available = unreserved_rooms(check_in, check_out) | ||
| if available == [] | ||
| raise StandardError, "There are no more available rooms for this date range!" | ||
| end |
There was a problem hiding this comment.
It probably reads better to write this as if available.empty?, or maybe inline it somehow ;)
lib/hotel_booker.rb
Outdated
| end | ||
|
|
||
|
|
||
| def make_block(rooms: nil, discount: nil, check_in: nil, check_out: nil) |
There was a problem hiding this comment.
This keyword args syntax makes these parameters optional: is that what you want?
lib/hotel_booker.rb
Outdated
| def make_block_reservation(id) | ||
| if @unreserved_block.length == 0 | ||
| raise StandardError, "There are no available Block reservations." | ||
| end |
There was a problem hiding this comment.
I think this is another block of code that checks if an array is empty in a different way? If so -- check my comment above!
lib/hotel_booker.rb
Outdated
| unreserved_block_rooms = [] | ||
| @unreserved_block.each do |reservation| | ||
| unreserved_block_rooms << reservation.room | ||
| end |
There was a problem hiding this comment.
Could possibly be a good chance to use map
| if reservation_dates.include?(date) | ||
| matching_reservations << reservation | ||
| end | ||
| end |
There was a problem hiding this comment.
Instead of using .each, might be good opportunity to use select
| @@ -0,0 +1,7 @@ | |||
| 1. I...lowkey cheated and made a collection of Reservations instead of a collection of Rooms. I would rewrite this part by making a subclass under Room called BookedRoom? | |||
There was a problem hiding this comment.
Not really sure what you mean by this tbh!
| @@ -0,0 +1,7 @@ | |||
| 1. I...lowkey cheated and made a collection of Reservations instead of a collection of Rooms. I would rewrite this part by making a subclass under Room called BookedRoom? | |||
|
|
|||
| 2. HotelBooker has a lot of WET code because I have to loop through several data structures (@unreserved_block, @reserved_block, @reservations)!! If I had focused the Wave 3 blocks of rooms on the ROOMS instead of reservations, probably wouldn't have created this mess ¯\_(ツ)_/¯ | |||
|
|
||
| 2. HotelBooker has a lot of WET code because I have to loop through several data structures (@unreserved_block, @reserved_block, @reservations)!! If I had focused the Wave 3 blocks of rooms on the ROOMS instead of reservations, probably wouldn't have created this mess ¯\_(ツ)_/¯ | ||
|
|
||
| 3. there are certain check_in and check_out arguments that are strings (as in Hotel::HotelBooker.new.make_reservation) and some that are an instance of Date (as in Hotel::HotelBooker.new.unreserved_rooms). Other arguments pass in a Hotel::DateRange (such as Hotel::Reservations). note to future goeun: make this less terrible |
| expect(@date_range2.overlaps?(@date_range4)).must_equal false | ||
| end | ||
| end | ||
| end |
There was a problem hiding this comment.
I love this DateRange class because it isolated the overlapping date logic to this one class, which is complex and tested in isolation... Beautiful :* truly inspiring :*
Hotel
Congratulations! You're submitting your assignment!
Comprehension Questions
HotelBookerfor all the dates ever booked). Thinking about how Chapter 3 Sandi Metz would be unimpressed with my agenda helped. Having a looming deadline made me feel rushed so I went with options that felt like it would let me get away with bare minimum. In retrospect, that was a pretty good design plan.HotelBookeris my factory class. Initially, I hadReservations createRooms andRooms refer toDateRanges but then it got too messy so I put all the logic into my main class. I see now thatTripDispatcherin Rideshare was set up to instantiate all the objects for a reason!HotelBooker). Easy. Things seemed to work.HotelBooker). Then I tried to create one more. But there were no more available rooms, so I raised anStandardError